<!--
 * @Author: ningjz
 * @Date: 2022-05-13 09:23:30
 * @FileDescription: 地图
-->
<template>
  <div class="c-map">
    <h3 class="title">{{ serviceData.goodsName }}</h3>
    <charts :params="mapState.params"></charts>
    <div class="bar-chart">
      <div class="label">
        <ul class="items">
          <li
            class="item"
            v-for="(item, index) of labelState.data"
            :key="index"
          >
            <p class="name">{{ item.name }}</p>
            <p class="value">{{ item.value }}</p>
          </li>
        </ul>
      </div>
      <div class="chart">
        <charts :params="barState.params"></charts>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent, reactive, watch, ref } from 'vue'
import httpRequest from '@/service'
import { gradientColor } from '@/charts/utils'
interface IChartState {
  params: any
  getData: (data?: any) => void
}
interface IChartDataItem {
  name: string
  value: number
  adcode: string
  unit: string
  list: IData[]
}
interface IData {
  name: string
  value: number
}
interface ILabelState {
  data: IData[]
  getData: (data?: any) => void
}
export default defineComponent({
  name: 'cMap',
  props: {
    serviceData: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  setup(props) {
    const average = ref(0)
    // 地图
    const mapState: IChartState = reactive({
      params: {
        loading: true,
        forceRedraw: true,
        map: {
          value: '价格'
        },
        adcode: '650000',
        options: {
          dataset: {
            dimensions: [],
            source: []
          },
          dataZoom: {
            disabled: true
          },
          xAxis: {
            disabled: true
          },
          yAxis: {
            disabled: true
          },
          visualMap: [
            {
              type: 'piecewise',
              pieces: [],
              show: true,
              left: 20,
              bottom: 50,
              align: 'left',
              precision: 1,
              orient: 'vertical',
              itemWidth: 30,
              itemHeight: 15,
              showLabel: true,
              itemGap: 5,
              textStyle: {
                color: '#fff',
                fontSize: 16
              },
              outOfRange: {
                color: '#def1ff'
              }
            }
          ],
          legend: {
            show: false
          },
          geo: [
            {
              map: '650000',
              roam: false,
              top: '4%',
              left: '2%',
              bottom: '7%',
              selectedMode: true,
              aspectScale: 0.85,
              zoom: 1,
              label: {
                show: true,
                color: '#fff',
                fontSize: 18,
                fontFamily: 'AliHYAiHei',
                formatter: (params: any) => {
                  let result = ''
                  let itemdata = mapState.params.options.series[0].data.find(
                    (item: any) => {
                      return item.name === params.name
                    }
                  )
                  let value = itemdata ? itemdata.value : 0
                  result = `{name|${params.name}}\n{value|${
                    value === 0 ? '' : value
                  }}`
                  return result
                },
                rich: {
                  name: {
                    fontSize: 18,
                    lineHeight: 24,
                    fontWeight: 'normal',
                    fontFamily: 'AliHYAiHei',
                    textShadowColor: 'rgba(0,0,0,.5)',
                    textShadowBlur: 10,
                    textShadowOffsetX: 0,
                    textShadowOffsetY: 5
                  },
                  value: {
                    fontSize: 20,
                    lineHeight: 24,
                    fontWeight: 'normal',
                    fontFamily: 'AliHYAiHei',
                    color: '#ffc22f',
                    textShadowColor: 'rgba(0,0,0,.5)',
                    textShadowBlur: 5,
                    textShadowOffsetX: 0,
                    textShadowOffsetY: 0
                  }
                }
              },
              itemStyle: {
                areaColor: '#17adbc',
                borderColor: '#fff',
                borderWidth: 2,
                shadowColor: 'rgba(0,0,0,0.6)',
                shadowBlur: 10,
                shadowOffsetX: 5,
                shadowOffsetY: 5
              },
              emphasis: {
                itemStyle: {
                  areaColor: gradientColor(['#efde1f', '#ea690a']),
                  borderColor: 'rgba(255,255,255,0.8)',
                  borderWidth: 1
                },
                label: {
                  color: '#fff',
                  rich: {
                    name: {
                      fontSize: 18,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      textShadowColor: 'rgba(0,0,0,.5)',
                      textShadowBlur: 10,
                      textShadowOffsetX: 0,
                      textShadowOffsetY: 5
                    },
                    value: {
                      fontSize: 20,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      color: '#fff'
                    }
                  }
                }
              },
              select: {
                itemStyle: {
                  areaColor: gradientColor(['#efde1f', '#ea690a']),
                  borderColor: 'rgba(255,255,255,0.8)',
                  borderWidth: 1
                },
                label: {
                  color: '#fff',
                  rich: {
                    name: {
                      fontSize: 18,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      textShadowColor: 'rgba(0,0,0,.5)',
                      textShadowBlur: 10,
                      textShadowOffsetX: 0,
                      textShadowOffsetY: 5
                    },
                    value: {
                      fontSize: 20,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      color: '#fff'
                    }
                  }
                }
              },
              z: 3
            }
          ],
          series: [
            {
              type: 'map',
              map: '650000',
              geoIndex: 0,
              aspectScale: 0.85,
              data: [],
              select: {
                itemStyle: {
                  areaColor: gradientColor(['#efde1f', '#ea690a']),
                  borderColor: 'rgba(255,255,255,0.8)',
                  borderWidth: 1
                },
                label: {
                  color: '#fff',
                  rich: {
                    name: {
                      fontSize: 18,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      textShadowColor: 'rgba(0,0,0,.5)',
                      textShadowBlur: 10,
                      textShadowOffsetX: 0,
                      textShadowOffsetY: 5
                    },
                    value: {
                      fontSize: 20,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      color: '#fff'
                    }
                  }
                }
              }
            },
            {
              type: 'map',
              map: '650000',
              aspectScale: 0.85,
              top: '6%',
              left: '3%',
              bottom: '5%',
              silent: true,
              itemStyle: {
                areaColor: '#064c8c',
                borderColor: 'rgba(255,255,255,0.5)',
                borderWidth: 1,
                shadowColor: 'rgba(0,0,0,1)',
                shadowBlur: 20,
                shadowOffsetX: 5,
                shadowOffsetY: 5
              }
            }
          ]
        },
        custom: true
      },
      getData: (params) => {
        mapState.params.loading = true
        httpRequest
          .get({
            url: 'M2P3Map',
            params
          })
          .then((res) => {
            if (res.code === 200) {
              average.value = res.average
              if (res.pieces.length === 1 && !res.pieces[0].max) {
                const pie = { ...res.pieces[0], max: '10' }
                mapState.params.options.visualMap[0].pieces = [pie]
              } else {
                mapState.params.options.visualMap[0].pieces = res.pieces
              }
              mapState.params.options.series[0].data = res.data
              barState.getData(mapState.params.options.series[0].data)
            } else {
              average.value = 0
              mapState.params.options.visualMap[0].pieces = [
                { color: '#18bed8', max: 10, min: 0 }
              ]
              mapState.params.options.series[0].data.forEach((i: any) => {
                i.value = 0
                i.isHide = true
              })
            }
            mapState.params.loading = false
          })
          .catch(() => {
            console.log('请求失败')
          })
      }
    })

    // 柱图
    const barState: IChartState = reactive({
      params: {
        loading: true,
        map: {
          value: '价格'
        },
        options: {
          dataset: {
            dimensions: ['name', 'value'],
            source: []
          },
          grid: {
            left: 60,
            bottom: 0
          },
          xAxis: [
            {
              type: 'value',
              inverse: true,
              show: false
            }
          ],
          yAxis: [
            {
              type: 'category',
              position: 'right',
              axisTick: {
                show: false
              },
              axisLine: {
                show: false
              },
              axisLabel: {
                fontSize: 14,
                color: '#9ccfff',
                formatter: function (value: any) {
                  if (value.length === 4) {
                    return value
                  } else {
                    return value + '    '
                  }
                }
              }
            }
          ],
          legend: {
            show: false
          },
          series: [
            {
              type: 'bar',
              showBackground: true,
              backgroundStyle: {
                color: 'rgba(68,156,255,0.1)'
              },
              label: {
                position: ['100%', 0],
                offset: [-75, 0],
                align: 'right'
              },
              itemStyle: {
                color: [[['#40c4ff', '#0d66ff'], 'right']]
              },
              barWidth: 15
            }
          ]
        }
      },
      getData: (data: IChartDataItem[]) => {
        barState.params.loading = true
        const dataSort = data.sort((a: IChartDataItem, b: IChartDataItem) => {
          return a.value - b.value
        })
        barState.params.options.dataset.source = dataSort
        labelState.getData(data)
        setTimeout(() => {
          barState.params.loading = false
        }, 0)
      }
    })

    // 数值展示
    const labelState: ILabelState = reactive({
      data: [],
      getData: (data: IChartDataItem[]) => {
        let maxItem: IData = {
            name: '',
            value: 0
          },
          minItem: IData = {
            name: '',
            value: 100000
          }
        data.forEach((item: IChartDataItem) => {
          if (item.value > 0) {
            maxItem = maxItem.value > item.value ? maxItem : item
            minItem = minItem.value < item.value ? minItem : item
          }
        })

        labelState.data[0] = {
          name: '自治区平均 : ',
          value: average.value
        }
        labelState.data[1] = {
          name: '最高价格 : ' + maxItem.name,
          value: maxItem.value
        }
        labelState.data[2] = {
          name: '最低价格 : ' + minItem.name,
          value: maxItem.value > 0 ? minItem.value : 0
        }
      }
    })
    watch(
      () => props.serviceData,
      (newVal) => {
        mapState.getData({
          serviceCode: newVal.serviceCode,
          taskCode: newVal.taskCode
        })
      }
    )
    return {
      mapState,
      barState,
      labelState
    }
  }
})
</script>
<style lang="less" scoped>
.c-map {
  position: relative;
  height: 100%;

  .title {
    position: absolute;
    top: 0;
    left: 20px;
    z-index: 99;
    font-size: 28px;
    color: #ffea00;
    line-height: 30px;
    text-align: center;
  }

  .label-title {
    position: absolute;
    top: 20px;
    right: 240px;
    width: 44px;
    z-index: 99;
    padding: 30px 0;
    font-size: 26px;
    font-weight: 700;
    color: #ffc924;
    background-color: rgba(0, 71, 157, 0.8);
    border-radius: 10px;
    text-align: center;
    transition: all 0.2s;
  }

  .bar-chart {
    position: absolute;
    top: 10%;
    right: 0px;
    width: 24%;
    height: 620px;
    display: flex;
    flex-direction: column;

    .label {
      ul.items {
        margin-right: 15px;

        li.item {
          display: flex;
          justify-content: space-between;
          line-height: 30px;

          &:first-child {
            p {
              color: #e3d119;
            }
          }

          p {
            font-family: 'AliHYAiHei';
            font-size: 16px;
          }

          &:nth-child(2) {
            p {
              // color: #f15e09;
              color: rgb(255, 38, 38);
            }
          }

          &:nth-child(3) {
            p {
              // color: #03f0b2;
              color: rgb(66, 255, 0);
            }
          }
        }
      }
    }

    .chart {
      flex: 1;
    }
  }
}
</style>
